<template>
  <div class="header">
    <div class="select">
      <slot name="select" />
    </div>

    <n-input
      v-model:value="params.keyword"
      @keydown.enter="handleSearch"
      clearable
      :placeholder="placeholder"
    >
      <template #suffix>
        <n-icon :component="Search" />
      </template>
    </n-input>
  </div>

  <n-data-table
    striped
    @update:sorter="sorterChange"
    :row-key="getRowKey"
    :columns="columns"
    :data="dataList"
    :max-height="height"
    :min-height="height"
  />

  <n-pagination
    @update:page="pageChange"
    v-model:page="params.pageNum"
    :page-size="10"
    size="large"
    :item-count="total"
  >
    <template #prefix="{ itemCount }"> 共 {{ itemCount }} 项 </template>
  </n-pagination>
</template>

<script setup lang="ts">
import { Search } from '@vicons/fa'
import { debounce } from '@/utils'

const props = defineProps({
  dataList: {
    type: Array,
    required: true
  },
  total: {
    type: Number,
    required: true
  },
  placeholder: {
    type: String,
    default: '请输入关键字'
  }
})

const columns = defineModel({ type: Object })

const emit = defineEmits(['getData'])

const height = 'calc(100vh - 250px)'
const params = ref({
  pageNum: 1,
  keyword: ''
})

const getRowKey = (row: any) => row.id

const pageChange = (page: number) => {
  params.value.pageNum = page
  emit('getData', params.value)
}

const sorterChange = (sorter: any) => {
  columns.value.forEach((column: any) => {
    if (column.sortOrder === undefined) return
    if (!sorter) {
      column.sortOrder = false
      return
    }
    if (column.key === sorter.columnKey) column.sortOrder = sorter.order
  })

  params.value.sorter = sorter.order
  params.value.pageNum = 1
  emit('getData', params.value)
}

watch(
  () => params.value.keyword,
  val => {
    if (!val.trim()) {
      params.value.pageNum = 1
      emit('getData', params.value)
    }
  }
)

const handleSearch = debounce(async () => {
  if (!params.value.keyword.trim()) return
  params.value.pageNum = 1
  emit('getData', params.value)
})
</script>

<style scoped lang="scss">
.header {
  display: flex;
  justify-content: space-between;

  .select {
    display: flex;
  }

  .n-input {
    width: 200px;
  }
}
</style>
